{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "Exercise4-Question.ipynb",
      "version": "0.3.2",
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UncprnB0ymAE",
        "colab_type": "text"
      },
      "source": [
        "Below is code with a link to a happy or sad dataset which contains 80 images, 40 happy and 40 sad. \n",
        "Create a convolutional neural network that trains to 100% accuracy on these images,  which cancels training upon hitting training accuracy of >.999\n",
        "\n",
        "Hint -- it will work best with 3 convolutional layers."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "7Vti6p3PxmpS",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 204
        },
        "outputId": "56c2bc0b-638e-462e-f9e2-d6610557405c"
      },
      "source": [
        "import tensorflow as tf\n",
        "import os\n",
        "import zipfile\n",
        "\n",
        "\n",
        "DESIRED_ACCURACY = 0.999\n",
        "\n",
        "!wget --no-check-certificate \\\n",
        "    \"https://storage.googleapis.com/laurencemoroney-blog.appspot.com/happy-or-sad.zip\" \\\n",
        "    -O \"/tmp/happy-or-sad.zip\"\n",
        "\n",
        "zip_ref = zipfile.ZipFile(\"/tmp/happy-or-sad.zip\", 'r')\n",
        "zip_ref.extractall(\"/tmp/h-or-s\")\n",
        "zip_ref.close()\n",
        "\n",
        "class myCallback(tf.keras.callbacks.Callback):\n",
        "    def on_epoch_end(self, epoch, logs={}):\n",
        "        if(logs.get('acc')>DESIRED_ACCURACY):\n",
        "            print(\"\\nReached 99.9% accuracy so cancelling training!\")\n",
        "            self.model.stop_training = True\n",
        "callbacks = myCallback()"
      ],
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "--2019-06-12 11:31:31--  https://storage.googleapis.com/laurencemoroney-blog.appspot.com/happy-or-sad.zip\n",
            "Resolving storage.googleapis.com (storage.googleapis.com)... 74.125.20.128, 2607:f8b0:400e:c09::80\n",
            "Connecting to storage.googleapis.com (storage.googleapis.com)|74.125.20.128|:443... connected.\n",
            "HTTP request sent, awaiting response... 200 OK\n",
            "Length: 2670333 (2.5M) [application/zip]\n",
            "Saving to: ‘/tmp/happy-or-sad.zip’\n",
            "\n",
            "\r/tmp/happy-or-sad.z   0%[                    ]       0  --.-KB/s               \r/tmp/happy-or-sad.z 100%[===================>]   2.55M  --.-KB/s    in 0.02s   \n",
            "\n",
            "2019-06-12 11:31:31 (143 MB/s) - ‘/tmp/happy-or-sad.zip’ saved [2670333/2670333]\n",
            "\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "6DLGbXXI1j_V",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 88
        },
        "outputId": "149b170f-1fe5-4488-dd77-714554ff3b33"
      },
      "source": [
        "# This Code Block should Define and Compile the Model\n",
        "model = tf.keras.models.Sequential([\n",
        "    tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(150, 150, 3)),\n",
        "    tf.keras.layers.MaxPooling2D(2, 2),\n",
        "    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),\n",
        "    tf.keras.layers.MaxPooling2D(2,2),\n",
        "    tf.keras.layers.Conv2D(32, (3,3), activation='relu'),\n",
        "    tf.keras.layers.MaxPooling2D(2,2),\n",
        "    tf.keras.layers.Flatten(),\n",
        "    tf.keras.layers.Dense(512, activation='relu'),\n",
        "    tf.keras.layers.Dense(1, activation='sigmoid')\n",
        "])\n",
        "\n",
        "from tensorflow.keras.optimizers import RMSprop\n",
        "\n",
        "model.compile(loss='binary_crossentropy',\n",
        "              optimizer=RMSprop(lr=0.001),\n",
        "              metrics=['acc'])"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/resource_variable_ops.py:435: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Colocations handled automatically by placer.\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4Ap9fUJE1vVu",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        },
        "outputId": "d84eb066-762b-4f39-96af-307c230edcde"
      },
      "source": [
        "# This code block should create an instance of an ImageDataGenerator called train_datagen \n",
        "# And a train_generator by calling train_datagen.flow_from_directory\n",
        "\n",
        "from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
        "\n",
        "train_datagen = ImageDataGenerator(rescale=1/255)\n",
        "\n",
        "train_generator = train_datagen.flow_from_directory(\n",
        "        \"/tmp/h-or-s\",  \n",
        "        target_size=(150, 150), \n",
        "        batch_size=10,\n",
        "        class_mode='binary')\n",
        "\n",
        "# Expected output: 'Found 80 images belonging to 2 classes'"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Found 80 images belonging to 2 classes.\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "48dLm13U1-Le",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 496
        },
        "outputId": "8d833296-ef80-47d6-9c63-055cb1d7a339"
      },
      "source": [
        "# This code block should call model.fit_generator and train for\n",
        "# a number of epochs. \n",
        "history = model.fit_generator(\n",
        "      train_generator,\n",
        "      steps_per_epoch=2,  \n",
        "      epochs=15,\n",
        "      verbose=1,\n",
        "      callbacks=[callbacks])\n",
        "    \n",
        "# Expected output: \"Reached 99.9% accuracy so cancelling training!\"\""
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Use tf.cast instead.\n",
            "Epoch 1/15\n",
            "8/8 [==============================] - 3s 370ms/step - loss: 1.5868 - acc: 0.6125\n",
            "Epoch 2/15\n",
            "8/8 [==============================] - 3s 326ms/step - loss: 0.4251 - acc: 0.8000\n",
            "Epoch 3/15\n",
            "8/8 [==============================] - 2s 312ms/step - loss: 0.2246 - acc: 0.9250\n",
            "Epoch 4/15\n",
            "8/8 [==============================] - 3s 320ms/step - loss: 0.2205 - acc: 0.9000\n",
            "Epoch 5/15\n",
            "8/8 [==============================] - 3s 313ms/step - loss: 0.1216 - acc: 0.9375\n",
            "Epoch 6/15\n",
            "8/8 [==============================] - 3s 325ms/step - loss: 0.1710 - acc: 0.9125\n",
            "Epoch 7/15\n",
            "8/8 [==============================] - 3s 318ms/step - loss: 0.0548 - acc: 0.9875\n",
            "Epoch 8/15\n",
            "8/8 [==============================] - 3s 321ms/step - loss: 0.0317 - acc: 0.9875\n",
            "Epoch 9/15\n",
            "8/8 [==============================] - 2s 311ms/step - loss: 0.1048 - acc: 0.9625\n",
            "Epoch 10/15\n",
            "8/8 [==============================] - 3s 320ms/step - loss: 0.0814 - acc: 0.9750\n",
            "Epoch 11/15\n",
            "7/8 [=========================>....] - ETA: 0s - loss: 0.0097 - acc: 1.0000\n",
            "Reached 99.9% accuracy so cancelling training!\n",
            "8/8 [==============================] - 3s 313ms/step - loss: 0.0086 - acc: 1.0000\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "4TJOlbu1d2Tb",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}